package com.chatim.nonamechatim.config;

import com.alibaba.fastjson2.JSON;
import com.chatim.nonamechatim.common.JwtUtil;
import com.chatim.nonamechatim.common.Res;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class JwtFilter extends GenericFilterBean {

    StringRedisTemplate redisTemplate;

    public JwtFilter(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setContentType("application/json;charset=utf-8");
        try {
            List<String> releaseStr = Arrays.asList("/login", "/index.html","/assets/", "/favicon.ico", "/header/");
            String uri = req.getRequestURI();
            if(releaseStr.stream().anyMatch(uri::contains)) {
                chain.doFilter(request, response);
                return;
            }

            // 获取请求中的token
            String token = req.getHeader("Authorization");
            if (token == null) {
                response.getWriter().write(JSON.toJSONString(Res.error("无认证令牌，请先登录")));
            } else {
                // 校验token
                token = token.replace("Bearer ", "");
                // 校验通过，返回认证后的 Authentication 对象
                Authentication authentication = JwtUtil.verifyToken(token);
                // 判断 redis 中是否有登录信息
                assert authentication != null;
                String rKey = "token:" + authentication.getName();
                String s = redisTemplate.opsForValue().get(rKey);
                if (s == null) {
                    // 令牌失效
                    response.getWriter().write(JSON.toJSONString(Res.error("令牌失效，请重新登录")));
                }
//                else {
//                    // 令牌有效，检查令牌过期时间进行续期
//                    Long expire = redisTemplate.getExpire(rKey);
//                    if(expire != null && expire < 10 * 60){
//                        // 令牌还有10分钟过期，重新设置过期时间
//                        redisTemplate.expire(rKey, Duration.ofSeconds(JwtUtil.EXPIRE_TIME));
//                    }
//                }
                SecurityContextHolder.getContext().setAuthentication(authentication);
                chain.doFilter(request, response);
            }
        } finally {
            // 清除上下文
            SecurityContextHolder.clearContext();
        }
    }
}
